package com.jiangxjsy.core.security.bcrypt;

import com.jiangxjsy.core.security.PasswordEncoder;
import com.jiangxjsy.core.security.kit.Algorithm;
import com.jiangxjsy.core.security.kit.EncodedCredential;
import org.springframework.security.crypto.bcrypt.BCrypt;

/**
 * wukong-crm-master
 * 蒋胜宇
 * 2025/6/5 14:18
 */

public class BCryptPasswordEncoder implements PasswordEncoder {
    private static final Algorithm ALGORITHM = Algorithm.BCRYPT;
    public static int clamp(int value, int min, int max) {
        return Math.max(min, Math.min(max, value));
    }


    /**
     * 哈希强度
     */
    private final int strength;

    public BCryptPasswordEncoder() {
        this.strength = 10;
    }

    public BCryptPasswordEncoder(int strength) {
        this.strength = clamp(strength, 4, 31);
    }

    /**
     * 加密原始密码
     *
     * @param rawPassword 原始密码（明文）
     * @param salt 盐值
     * @return 加密后的密码（包含算法标识）
     */
    @Override
    public EncodedCredential encode(CharSequence rawPassword, String salt) {
        String hash = BCrypt.hashpw(rawPassword.toString(), BCrypt.gensalt(strength));
        return new EncodedCredential(hash, null, ALGORITHM);
    }

    /**
     * 加密原始密码
     *
     * @param rawPassword 原始密码（明文）
     * @return 加密后的密码（包含算法标识）
     */
    @Override
    public EncodedCredential encode(CharSequence rawPassword) {
        return encode(rawPassword, null);
    }

    /**
     * 验证密码是否匹配
     *
     * @param rawPassword 原始密码（明文）
     * @param credential 已加密的凭证（含盐值和算法）
     * @return 是否匹配
     */
    @Override
    public boolean matches(CharSequence rawPassword, EncodedCredential credential) {
        return BCrypt.checkpw(rawPassword.toString(), credential.getPasswordHash());
    }

    /**
     * 获取算法名称
     *
     * @return 算法名称
     */
    @Override
    public String getAlgorithm() {
        return ALGORITHM.getAlgorithm();
    }
}
